package com.gccloud.design.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gccloud.design.dao.*;
import com.gccloud.design.dto.*;
import com.gccloud.design.entity.*;
import com.gccloud.design.feign.BwpOperDockingClient;
import com.gccloud.design.service.SdApiDefineService;
import com.gccloud.design.service.SdParticipantConfService;
import com.gccloud.design.service.SdRepoTimeLimitService;
import com.gccloud.design.utils.ConstantUtil;
import com.gccloud.design.utils.GroovyUtil;
import com.gccloud.design.vo.SdApiDefineVo;
import com.gccloud.idc.common.utils.RestTemplateUtils;
import com.gccloud.idc.components.cache.constant.CommonRedisGroupNameConst;
import com.gccloud.idc.components.cache.RedisAdapter;
import com.gccloud.idc.security.shiro.UserUtils;
import com.gccloud.starter.common.exception.GlobalException;
import com.gccloud.starter.common.utils.BeanConvertUtils;
import com.gccloud.starter.common.vo.R;
import com.gccloud.starter.core.vo.PageVO;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author wu.yumin
 * @version 1.0.0
 * @date 2021/6/10 21:05
 */
@Slf4j
@Service
public class SdApiDefineServiceImpl extends ServiceImpl<SdApiDefineDao, SdApiDefineEntity> implements SdApiDefineService {

    /**
     * 流程平台生成环节的返回状态码
     */
    private static final Integer BWP_CODE = 200;

    /**
     * API提供方
     * 1：综合调度中心
     */
    private static final String API_PROVIDER = "1";
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Resource
    private RedisAdapter ctgRedisUtils;

    @Resource
    private SdApiDefineDao sdApiDefineDao;
    @Resource
    private SdApiAuthRuleDao sdApiAuthRuleDao;
    @Resource
    private SdApiExphRuleDao sdApiExphRuleDao;
    @Resource
    private SdApiCompRuleDao sdApiCompRuleDao;
    @Resource
    private SdApiCallRuleDao sdApiCallRuleDao;
    @Resource
    private SdApiParamDao sdApiParamDao;
    @Resource
    private SdApiFlowRepoBindDao sdApiFlowRepoBindDao;
    @Resource
    private SdRepoParticipantConfDao sdRepoParticipantConfDao;
    @Resource
    private BwpOperDockingClient bwpOperDockingClient;
    @Resource
    private SdParticipantConfService sdParticipantConfService;
    @Resource
    private SdRepoTimeLimitService sdRepoTimeLimitService;
    @Resource
    private SdApiAbilityBindDao sdApiAbilityBindDao;
    @Resource
    private DICReasonDao dicReasonDao;
    @Resource
    private RestTemplateUtils restTemplateUtils;

    @Override
    public boolean insertApiDefine(SdApiDefineEntity entity) {
        entity.setApiStatus("10D");
        entity.setShardingId(0);
        try {
            return saveOrUpdate(entity);
        } catch (Exception e) {
            log.error(ExceptionUtils.getStackTrace(e));
            return false;
        }
    }

    @Override
    public boolean delApiDefine(Long apiId) {
        if (apiId == null || apiId == 0) {
            throw new IllegalArgumentException("记录不存在");
        }
        UpdateWrapper<SdApiDefineEntity> updateWrapper = new UpdateWrapper();
        updateWrapper.set("STATUS", 1).eq("API_ID", apiId);
        try {
            return update(updateWrapper);
        } catch (Exception e) {
            log.error(ExceptionUtils.getStackTrace(e));
            return false;
        }
    }

    @Override
    public boolean updateApiDefine(SdApiDefineEntity entity) {

        if (entity.getApiId() == null || entity.getApiId() == 0) {
            throw new IllegalArgumentException("记录不存在");
        }
        UpdateWrapper<SdApiDefineEntity> updateWrapper = new UpdateWrapper();
        try {
            updateWrapper.set("API_NAME", entity.getApiName())
                    .set("API_CODE", entity.getApiCode())
                    .set("API_VERSION", entity.getApiVersion())
                    .set("API_STATUS", entity.getApiStatus())
                    .set("API_URL", entity.getApiIp())
                    .set("API_PROVIDER", entity.getApiProvider())
                    .set("API_CONSUMER", entity.getApiConsumer())
                    .set("API_TYPE", entity.getApiType())
                    .set("IS_CORE", entity.getIsCore())
                    .set("CATALOG_ID", entity.getCatalogId())
                    .set("CATALOG_CODE", entity.getCatalogCode())
                    .set("CATALOG_NAME", entity.getCatalogName())
                    .set("COMMENTS", entity.getComments())
                    .set("MODIFIED_NAME", entity.getModifiedName())
                    .set("MODIFIED_TIME", new Date())
                    .set("MODIFIED_ID", entity.getModifiedId())
                    .eq("API_ID", entity.getApiId());
            return update(updateWrapper);
        } catch (Exception e) {
            log.error(ExceptionUtils.getStackTrace(e));
            return false;
        }
    }

    /**
     * 条件分页查询 API定义列表
     *
     * @param sdApiDefineDto API定义dto
     * @return PageVO<SdApiDefineEntity>
     */
    @Override
    public Map<String, Object> selectApiDefine(SdApiDefineDto sdApiDefineDto) {

        Page<SdApiDefineEntity> searchPage = new Page<>(sdApiDefineDto.getCurrent(), sdApiDefineDto.getSize());

        QueryWrapper<SdApiDefineEntity> wrapper = new QueryWrapper<>();
        if (sdApiDefineDto.getApiName() != null && !"".equals(sdApiDefineDto.getApiName())) {
            wrapper.like("api_name", sdApiDefineDto.getApiName());
        }
        if (sdApiDefineDto.getApiCode() != null && !"".equals(sdApiDefineDto.getApiCode())) {
            wrapper.like("api_code", sdApiDefineDto.getApiCode());
        }
        if (sdApiDefineDto.getApiClass() != null && !"".equals(sdApiDefineDto.getApiClass())) {
            wrapper.eq("api_class", sdApiDefineDto.getApiClass());
        }
        if (sdApiDefineDto.getApiType() != null && !"".equals(sdApiDefineDto.getApiType())) {
            wrapper.eq("api_type", sdApiDefineDto.getApiType());
        }
        if (sdApiDefineDto.getApiProvider() != null && !"".equals(sdApiDefineDto.getApiProvider())) {
            wrapper.eq("api_provider", sdApiDefineDto.getApiProvider());
        }
        if (sdApiDefineDto.getApiConsumer() != null && !"".equals(sdApiDefineDto.getApiConsumer())) {
            wrapper.eq("api_consumer", sdApiDefineDto.getApiConsumer());
        }
        if(sdApiDefineDto.getCatalogId()!=0){
            wrapper.eq("CATALOG_ID",sdApiDefineDto.getCatalogId());
        }
        if (StringUtils.isNotBlank(sdApiDefineDto.getApiStatus())){
            wrapper.eq("api_status", sdApiDefineDto.getApiStatus()).orderByDesc("MODIFIED_TIME");
        }else {
            wrapper.ne("api_status", "10DL").orderByDesc("MODIFIED_TIME");
        }
        wrapper.eq("api_version","V0.0.0");
        IPage<SdApiDefineEntity> page = page(searchPage, wrapper);

        List<SdApiDefineEntity> records = page.getRecords();
        PageVO<SdApiDefineVo> convert1 = BeanConvertUtils.convert(new PageVO<>(page), PageVO.class);
        List<SdApiDefineVo> voList = Lists.transform(records, (entity) -> {
            SdApiDefineVo convert = BeanConvertUtils.convert(entity, SdApiDefineVo.class);
            SdApiDefineVo vo = this.baseMapper.getVersionByApiCode(entity.getApiCode());
            convert.setApiVersion( vo == null ?"V0.0.0":vo.getApiVersion());
            convert.setBwpRepoName( vo == null ?"":vo.getBwpRepoName());
            return convert;
        });
        convert1.setList(voList);
        Map<String,Object> map = new HashMap<>(4);
        map.put("delCount",this.baseMapper.selectApiCount(sdApiDefineDto.setApiStatus("10DL")));
        map.put("createCount",this.baseMapper.selectApiCount(sdApiDefineDto.setApiStatus("10C")));
        map.put("publishCount",this.baseMapper.selectApiCount(sdApiDefineDto.setApiStatus("10P")));
        map.put("data",convert1);
        return map;
    }

    /**
     * 删除API定义
     *
     * @param apiIds api标识数组
     * @return 删除结果
     */
    @Override
    public boolean deleteApiDefine(Integer[] apiIds) {
        boolean deleteApiDefine = false;
        int deleteApiBind = 0;
        for (Integer apiId : apiIds) {
            QueryWrapper<SdApiDefineEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("api_status","api_code").eq("api_id",apiId);
            SdApiDefineEntity entity = getOne(queryWrapper);
            if ("10P".equals(entity.getApiStatus())){
                update(new UpdateWrapper<SdApiDefineEntity>().set("api_status","10D")
                        .eq("api_code",entity.getApiCode())
                .eq("api_version","V0.0.0"));
            }
            UpdateWrapper<SdApiDefineEntity> updateWrapper = new UpdateWrapper();
            // 状态等于10DL 代表删除
            updateWrapper.set("api_status", "10DL").eq("api_id", apiId);
            try {
                deleteApiDefine = update(updateWrapper);
                if (deleteApiDefine) {
                    // 删除API能力绑定
                    UpdateWrapper<SdApiAbilityBindEntity> wrapper = new UpdateWrapper();
                    wrapper.eq("api_id", apiId);
                    deleteApiBind = sdApiAbilityBindDao.delete(wrapper);
                }
            } catch (Exception e) {
                log.error(ExceptionUtils.getStackTrace(e));
            }
        }
        return deleteApiDefine && deleteApiBind > 0;
    }

    /**
     * 新增/修改 API定义
     *
     * @param dto API定义的dto
     * @return 增加或修改结果
     */
    @Override
    public boolean addOrUpApiDefine(SdApiAddDto dto) {
        int apiBindResult = 0;
        String userId = UserUtils.getCurrentUserName();
        String userName = UserUtils.getCurrentUser().getRealName();

        if (dto.getApiId() == null || dto.getApiId() == 0) {
            // 新增api
            SdApiDefineEntity entity = new SdApiDefineEntity();
            try {
                entity.setBisopId("1").setBisopCode("RES").setRelaSrId(1).setRelaSrType("CFS");
                entity.setShardingId(0);
                entity.setApiVersion(dto.getApiVersion());
                entity.setApiStatus(dto.getApiStatus());
                // API版本 默认v1
                entity.setIsCore("Y");
                entity.setCreatedId(userId).setModifiedId(userId);
                entity.setCreatedName(userName).setModifiedName(userName);
                entity.setCreatedTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                entity.setModifiedTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                entity.setApiName(dto.getApiName()).setApiCode(dto.getApiCode()).setApiProvider(dto.getApiProvider()).setApiConsumer(dto.getApiConsumer());
                entity.setApiType(dto.getApiType()).setApiIp(dto.getApiIp());
                entity.setInteractionMode(dto.getInteractionMode());
                entity.setDataFormat(dto.getDataFormat());
                entity.setComments(dto.getComments());
                entity.setCallTimeOut(dto.getCallTimeOut());
                entity.setIsTry(dto.getIsTry());
                entity.setTryCount(dto.getTryCount());
                entity.setTryInterval(dto.getTryInterval());
                entity.setCatalogId(dto.getCatalogId());
                entity.setApiProtocol(dto.getApiProtocol());
                entity.setApiAction(dto.getApiAction());
                entity.setApiPath(dto.getApiPath());
                if(dto.getApiProvider().equals("1") && dto.getApiProvider().equals(dto.getApiConsumer())){
                    entity.setApiClass("INSIDE");
                }else{
                    entity.setApiClass("OUTSIDE");
                }
                if(dto.getCatalogId()==0){
                    entity.setCatalogName("电源割接");
                    entity.setCatalogCode("1001");
                }else {
                    entity.setCatalogName(dto.getCatalogName());
                    entity.setCatalogCode(dto.getCatalogCode());
                }
                int insert = sdApiDefineDao.insert(entity);
                if (insert > 0) {
                    // API能力绑定入库
                    SdApiAbilityBindEntity sdApiAbilityBindEntity = new SdApiAbilityBindEntity();
                    sdApiAbilityBindEntity.setApiAbilityUrl(dto.getApiIp())
                            .setApiAbilitySource(dto.getApiAbilitySource())
                            .setShardingId(0)
                            .setApiId(entity.getApiId());
                    apiBindResult = sdApiAbilityBindDao.insert(sdApiAbilityBindEntity);
                }
                return insert > 0 && apiBindResult > 0;
            } catch (Exception e) {
                log.error(ExceptionUtils.getStackTrace(e));
                return false;
            }
        } else {
            // 修改api
            try {
                // 修改版本
                SdApiDefineEntity entity = sdApiDefineDao.selectById(dto.getApiId());
                UpdateWrapper<SdApiDefineEntity> updateWrapper = new UpdateWrapper();

                updateWrapper.set("api_name", dto.getApiName())
                        .set("api_code", dto.getApiCode())
                        .set("api_version", dto.getApiVersion())
                        .set("api_ip", dto.getApiIp())
                        .set("api_provider", dto.getApiProvider())
                        .set("api_consumer",dto.getApiConsumer())
                        .set("api_type", dto.getApiType())
                        .set("api_class", dto.getApiClass())
                        .set("is_core", dto.getIsCore())
                        .set("catalog_name", dto.getCatalogName())
                        .set("catalog_code", dto.getCatalogCode())
                        .set("catalog_id", dto.getCatalogId())
                        .set("modified_time", new Date())
                        .set("data_format", dto.getDataFormat())
                        .set("interaction_mode", dto.getInteractionMode())
                        .set("comments", dto.getComments())
                        .set("modified_id", userId)
                        .set("modified_name", userName)
                        .set("comments", dto.getComments())
                        .set("api_version", dto.getApiVersion())
                        .set("is_try",dto.getIsTry())
                        .set("call_time_out",dto.getCallTimeOut())
                        .set("try_count",dto.getTryCount())
                        .set("try_interval",dto.getTryInterval())
                        .set("api_path",dto.getApiPath())
                        .set("api_ip",dto.getApiIp())
                        .set("api_protocol",dto.getApiProtocol())
                        .set("api_action",dto.getApiAction())
                        .eq("api_id", dto.getApiId());
                boolean update = update(updateWrapper);
                if (update) {
                    UpdateWrapper<SdApiAbilityBindEntity> wrapper = new UpdateWrapper();
                    wrapper.eq("api_id", dto.getApiId());
                    SdApiAbilityBindEntity sdApiAbilityBindEntity = new SdApiAbilityBindEntity();
                    sdApiAbilityBindEntity.setApiAbilitySource(dto.getApiAbilitySource()).setApiAbilityUrl(dto.getApiAbilityUrl());
                    apiBindResult = sdApiAbilityBindDao.update(sdApiAbilityBindEntity, wrapper);
                }
                return update && apiBindResult > 0;
            } catch (Exception e) {
                log.error(ExceptionUtils.getStackTrace(e));
                return false;
            }
        }
    }

    /**
     * 检查API编码是否重复
     *
     * @param apiCode API编码
     * @param apiId   API标识
     * @return 检查结果
     */
    @Override
    public boolean checkApiCodeRepeat(String apiCode, Integer apiId) {
        QueryWrapper<SdApiDefineEntity> wrapper = new QueryWrapper<>();
        if (apiId != null) {
            String oldApiCode = sdApiDefineDao.selectById(apiId).getApiCode();
            if (oldApiCode.equals(apiCode)) {
                return false;
            }
        }
        wrapper.eq("api_code", apiCode).ne("api_status", 1);
        return sdApiDefineDao.selectCount(wrapper) > 0;
    }

    /**
     * 基于apiId 查询能力绑定信息
     *
     * @param apiId api标识
     * @return SdApiAbilityBindEntity
     */
    @Override
    public SdApiAbilityBindEntity queryAbility(Integer apiId) {
        QueryWrapper<SdApiAbilityBindEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("api_id", apiId);
        return sdApiAbilityBindDao.selectOne(wrapper);
    }

    /**
     * 查询调用机制、安全策略、异常处理机制、补偿机制
     *
     * @param apiId api标识
     * @return Map<String, Object>
     */
    @Override
    public Map<String, Object> selectPolicyList(Integer apiId) {
        Map<String, Object> resultMap = new HashMap<>();
        QueryWrapper<SdApiAuthRuleEntity> sdApiAuthRuleEntityQueryWrapper = new QueryWrapper<>();
        QueryWrapper<SdApiExphRuleEntity> sdApiExphRuleEntityQueryWrapper = new QueryWrapper<>();
        QueryWrapper<SdApiCompRuleEntity> sdApiCompRuleEntityQueryWrapper = new QueryWrapper<>();
        QueryWrapper<SdApiCallRuleEntity> sdApiCallRuleEntityQueryWrapper = new QueryWrapper<>();
        sdApiAuthRuleEntityQueryWrapper.eq("api_id", apiId);
        sdApiExphRuleEntityQueryWrapper.eq("api_id", apiId);
        sdApiCompRuleEntityQueryWrapper.eq("api_id", apiId);
        sdApiCallRuleEntityQueryWrapper.eq("api_id", apiId);
        List<SdApiAuthRuleEntity> entity1 = sdApiAuthRuleDao.selectList(sdApiAuthRuleEntityQueryWrapper);
        List<SdApiExphRuleEntity> entity2 = sdApiExphRuleDao.selectList(sdApiExphRuleEntityQueryWrapper);
        List<Map<String, Object>> list = new ArrayList<>();
        for (SdApiExphRuleEntity s : entity2) {
            Map<String, Object> map = new HashMap<>();
            Integer expReasonId = s.getExpReasonId();
            DICReasonEntity dicReasonEntity = dicReasonDao.selectOneReason(expReasonId);
            map.put("id", dicReasonEntity.getId());
            map.put("label", dicReasonEntity.getLabel());
            list.add(map);
        }
        List<SdApiCompRuleEntity> entity3 = sdApiCompRuleDao.selectList(sdApiCompRuleEntityQueryWrapper);
        for (SdApiCompRuleEntity s : entity3) {
            Map<String, Object> map = new HashMap<>();
            Integer expReasonId = s.getExpReasonId();
            DICReasonEntity dicReasonEntity = dicReasonDao.selectOneReason(expReasonId);
            map.put("label", dicReasonEntity.getLabel());
            map.put("id", dicReasonEntity.getId());
            list.add(map);
        }
        List<SdApiCallRuleEntity> entity4 = sdApiCallRuleDao.selectList(sdApiCallRuleEntityQueryWrapper);
        resultMap.put("authRule", entity1);
        resultMap.put("exphRule", entity2);
        resultMap.put("compRule", entity3);
        resultMap.put("callRule", entity4);
        resultMap.put("reasonIdAndName", list);
        return resultMap;
    }

    /**
     * 新增或修改调用机制、安全策略、异常处理机制、补偿机制
     *
     * @param policyMap policyMap
     * @return int
     */
    @Override
    public int insertOrUpdatePolicy(Map<String, PolicyListDto> policyMap) {
        PolicyListDto ruleList = policyMap.get("ruleList");
        Long apiId = ruleList.getApiId();
        List<SdApiAuthRuleEntity> sdApiAuthRuleList = ruleList.getSdApiAuthRuleList();
        List<SdApiExphRuleEntity> sdApiExphRuleEntityList = ruleList.getSdApiExphRuleList();
        List<SdApiCompRuleEntity> sdApiCompRuleEntityList = ruleList.getSdApiCompRuleList();
        List<SdApiCallRuleEntity> sdApiCallRuleEntityList = ruleList.getSdApiCallRuleList();
        int num, result1 = 0, result2 = 0, result3 = 0, result4 = 0;
        if (sdApiAuthRuleList != null && sdApiAuthRuleList.size() > 0) {
            for (SdApiAuthRuleEntity entity : sdApiAuthRuleList) {
                Integer id = entity.getId();
                if (id == null) {
                    // 新增
                    entity.setShardingId(0).setApiId(apiId);
                    result1 = sdApiAuthRuleDao.insert(entity);
                } else {
                    UpdateWrapper<SdApiAuthRuleEntity> updateWrapper = new UpdateWrapper<>();
                    updateWrapper.set("auth_ip_list", entity.getAuthIpList()).set("auth_key", entity.getAuthKey()).set("http_type", entity.getHttpType())
                            .set("sys_name", entity.getSysName()).set("sys_id", entity.getSysId());
                    updateWrapper.eq("id", entity.getId()).eq("api_id", apiId);
                    result1 = sdApiAuthRuleDao.update(entity, updateWrapper);
                }
            }
        }
        if (sdApiExphRuleEntityList != null && sdApiExphRuleEntityList.size() > 0) {
            for (SdApiExphRuleEntity entity : sdApiExphRuleEntityList) {
                Integer id = entity.getId();
                if (id == null) {
                    // 新增
                    entity.setShardingId(0).setApiId(apiId);
                    result2 = sdApiExphRuleDao.insert(entity);
                } else {
                    UpdateWrapper<SdApiExphRuleEntity> updateWrapper = new UpdateWrapper<>();
                    updateWrapper.set("exp_reason_id", entity.getExpReasonId())
                            .set("handle_type", entity.getHandleType()).set("handle_type_name", entity.getHandleTypeName())
                            .set("target_api_id", entity.getTargetApiId());
                    updateWrapper.eq("id", entity.getId()).eq("api_id", apiId);
                    result2 = sdApiExphRuleDao.update(entity, updateWrapper);
                }
            }
        }
        if (sdApiCompRuleEntityList != null && sdApiCompRuleEntityList.size() > 0) {
            for (SdApiCompRuleEntity entity : sdApiCompRuleEntityList) {
                Integer id = entity.getId();
                if (id == null) {
                    // 新增
                    entity.setShardingId(0).setApiId(apiId);
                    result3 = sdApiCompRuleDao.insert(entity);
                } else {
                    UpdateWrapper<SdApiCompRuleEntity> updateWrapper = new UpdateWrapper<>();
                    updateWrapper.set("exp_reason_id", entity.getExpReasonId()).set("comp_api_id", entity.getCompApiId());
                    updateWrapper.eq("id", entity.getId()).eq("api_id", apiId);
                    result3 = sdApiCompRuleDao.update(entity, updateWrapper);
                }
            }
        }
        if (sdApiCallRuleEntityList != null && sdApiCallRuleEntityList.size() > 0) {
            for (SdApiCallRuleEntity entity : sdApiCallRuleEntityList) {
                Integer id = entity.getId();
                if (id == null) {
                    // 新增
                    if (entity.getCallTimeOut() != null
                            && !StringUtils.isNotBlank(entity.getIsIdempotent())
                            && !StringUtils.isNotBlank(entity.getIsIdempotent())
                            && !StringUtils.isNotBlank(entity.getIsIdempotent())
                            && entity.getTryCount() != null
                            && entity.getTryInterval() != null
                    ) {
                        entity.setShardingId(0).setApiId(apiId);
                        result4 = sdApiCallRuleDao.insert(entity);
                    }
                } else {
                    UpdateWrapper<SdApiCallRuleEntity> updateWrapper = new UpdateWrapper<>();
                    updateWrapper.set("call_time_out", entity.getCallTimeOut()).set("is_try", entity.getIsTry())
                            .set("try_interval", entity.getTryInterval()).set("try_count", entity.getTryCount())
                            .set("is_idempotent", entity.getIsIdempotent()).set("request_type", entity.getRequestType());
                    updateWrapper.eq("id", entity.getId()).eq("api_id", apiId);
                    if (entity.getCallTimeOut() != null
                            && !StringUtils.isNotBlank(entity.getIsIdempotent())
                            && !StringUtils.isNotBlank(entity.getIsIdempotent())
                            && !StringUtils.isNotBlank(entity.getIsIdempotent())
                            && entity.getTryCount() != null
                            && entity.getTryInterval() != null
                    ) {
                        result4 = sdApiCallRuleDao.update(entity, updateWrapper);
                    }
                }
            }
        }
        num = result1 + result2 + result3 + result4;
        return num;
    }

    /**
     * 删除调用机制、安全策略、异常处理机制、补偿机制
     *
     * @param policyMap policyMap
     * @return int
     */
    @Override
    public int deletePolicy(Map<String, PolicyListDto> policyMap) {
        PolicyListDto ruleList = policyMap.get("ruleList");
        int num, result1 = 0, result2 = 0, result3 = 0, result4 = 0;
        List<SdApiAuthRuleEntity> sdApiAuthRuleList = ruleList.getSdApiAuthRuleList();
        List<SdApiExphRuleEntity> sdApiExphRuleEntityList = ruleList.getSdApiExphRuleList();
        List<SdApiCompRuleEntity> sdApiCompRuleEntityList = ruleList.getSdApiCompRuleList();
        List<SdApiCallRuleEntity> sdApiCallRuleEntityList = ruleList.getSdApiCallRuleList();
        if (sdApiAuthRuleList != null && sdApiAuthRuleList.size() > 0) {
            for (SdApiAuthRuleEntity entity : sdApiAuthRuleList) {
                Integer id = entity.getId();
                if (id != null) {
                    // 删除
                    result1 = sdApiAuthRuleDao.deleteById(id);
                }
            }
        }
        if (sdApiExphRuleEntityList != null && sdApiExphRuleEntityList.size() > 0) {
            for (SdApiExphRuleEntity entity : sdApiExphRuleEntityList) {
                Integer id = entity.getId();
                if (id != null) {
                    // 删除
                    result2 = sdApiExphRuleDao.deleteById(id);
                }
            }
        }
        if (sdApiCompRuleEntityList != null && sdApiCompRuleEntityList.size() > 0) {
            for (SdApiCompRuleEntity entity : sdApiCompRuleEntityList) {
                Integer id = entity.getId();
                if (id != null) {
                    // 删除
                    result3 = sdApiCompRuleDao.deleteById(id);
                }
            }
        }
        if (sdApiCallRuleEntityList != null && sdApiCallRuleEntityList.size() > 0) {
            for (SdApiCallRuleEntity entity : sdApiCallRuleEntityList) {
                Integer id = entity.getId();
                if (id != null) {
                    // 删除
                    result4 = sdApiCallRuleDao.deleteById(id);
                }
            }
        }
        num = result1 + result2 + result3 + result4;
        return num;
    }

    /**
     * 查询补偿API
     *
     * @param apiId api标识
     * @return List<SdApiDefineEntity>
     */
    @Override
    public List<SdApiDefineEntity> selectCompApiId(Integer apiId) {
        QueryWrapper<SdApiDefineEntity> wrapper = new QueryWrapper<>();
        wrapper.ne("api_id", apiId).ne("api_status", 1);
        return sdApiDefineDao.selectList(wrapper);
    }

    /**
     * 参数配置
     *
     * @param entity api参数配置entity
     * @return int
     */
    @Override
    public int paramConfig(SdApiParamEntity entity) {
        int insert = 0;
        entity.setShardingId(0);
        if (entity.getApiId() != null && !StringUtils.isNotBlank(entity.getParamType())
                && !StringUtils.isNotBlank(entity.getParamTemplate())
                && !StringUtils.isNotBlank(entity.getParamAnalyzeTemplate())
                && !StringUtils.isNotBlank(entity.getMockInparam())) {
            if (entity.getId() != null) {
                UpdateWrapper<SdApiParamEntity> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("id", entity.getId());
                insert = sdApiParamDao.update(entity, updateWrapper);
            } else {
                insert = sdApiParamDao.insert(entity);
            }

        }
        return insert;
    }

    /**
     * 参数配置--模拟测试
     *
     * @param
     * @return String
     */
    @Override
    public String paramConfigTest(ApiTestDto vo) {
        Map<String,Object> form = vo.getForm();
        Map<String,String> headers = vo.getHeaders();
        String url = "HTTPS".equalsIgnoreCase(vo.getApiProtocol())?("https://" + vo.getUrl()):("http://" + vo.getUrl());
        String callResult = null;
        try {
            if("INSIDE".equals(vo.getApiClass()) && url.indexOf("{apiCode}") > -1){
                String res = restTemplateUtils.postJson(url, vo.getRequest(), 10000, headers,vo.getApiCode());
                return res;
            }
            //get
            if("HTTP".equalsIgnoreCase(vo.getApiProtocol())){
                if("GET".equals(vo.getApiAction())){
                    callResult = vo.getForm().isEmpty() ? restTemplateUtils.get(url,10000,headers):
                            restTemplateUtils.get(url,form,10000,headers);
                }else if("POST".equals(vo.getApiAction())) {
                    callResult = "3".equals(vo.getDataFormat()) ? restTemplateUtils.postForm(url,form,10000,headers):
                    restTemplateUtils.postJson(url,vo.getRequest(),10000,headers);
                }
            }else if("HTTPS".equalsIgnoreCase(vo.getApiProtocol())){
                // callResult = restTemplateUtils.postJson(api.getApiIp(),param,10000);
            }else {
                //webService
                callResult = restTemplateUtils.invokeHttpWebService(url,vo.getRequest(),10000,null,headers);
            }
        }catch (Exception e){
            log.error(e.getMessage(),e);
            callResult = ExceptionUtils.getStackTrace(e);
        }

        return callResult;
    }

    public static String constructUrl(String url,Map<String,Object> paramMap){
        if (org.springframework.util.StringUtils.isEmpty(paramMap)){
            return url;
        }
        StringBuffer sb = new StringBuffer(url).append("?");
        for (String key:paramMap.keySet()) {
            sb.append(key).append("=").append("{").append(key).append("}").append("&");
        }
        sb.replace(sb.length() - 1, sb.length(), "");
        return sb.toString();
    }

    @Override
    public Boolean saveInparam(SdApiParamEntity entity) {
        UpdateWrapper<SdApiParamEntity> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("mock_inparam", entity.getMockInparam()).eq("id", entity.getId());
        int update = sdApiParamDao.update(entity, updateWrapper);
        if (update == 0) {
            throw new GlobalException("数据库更新失败");
        }
        return update > 0;
    }

    /**
     * 基于apiId 查询参数配置
     *
     * @param apiId api标识
     * @return SdApiParamEntity
     */
    @Override
    public SdApiParamEntity queryParamConfig(Integer apiId) {
        if (apiId != null) {
            QueryWrapper<SdApiParamEntity> wrapper = new QueryWrapper<>();
            wrapper.eq("api_id", apiId);
            return sdApiParamDao.selectOne(wrapper);
        } else {
            return null;
        }
    }

    /**
     * 查询所有障碍原因
     *
     * @return List<DICReasonEntity>
     */
    @Override
    public List<DICReasonEntity> queryDicReason() {
        return dicReasonDao.selectAll();
    }

    /**
     * 基于apiId 查询API环节绑定信息
     *
     * @param apiId api标识
     * @return SdApiFlowRepoBindDto
     */
    @Override
    public SdApiFlowRepoBindDto queryApiRepoInfo(Integer apiId) {
        SdApiFlowRepoBindDto sdApiFlowRepoBindDto = sdApiFlowRepoBindDao.queryApiRepoInfo(apiId);
        if (sdApiFlowRepoBindDto != null && sdApiFlowRepoBindDto.getBwpRepoId() != null) {
            List<SdRepoParticipantConfEntity> list = sdRepoParticipantConfDao.getRepoParticipant(sdApiFlowRepoBindDto.getBwpRepoId());
            sdApiFlowRepoBindDto.setList(list);
        }
        return sdApiFlowRepoBindDto;
    }

    /**
     * API定义生成环节
     *
     * @param dto 生成环节dto
     * @return boolean
     */
    @Override
    public boolean apiRepoBind(SdApiFlowRepoBindDto dto) {
        Map<String, Object> paramMap = new HashMap<>();
        Date date = new Date();
        SdApiFlowRepoBindEntity sdApiFlowRepoBindEntity = new SdApiFlowRepoBindEntity();
        SdRepoLimitTimeEntity sdRepoLimitTimeDto = new SdRepoLimitTimeEntity();
        paramMap.put("joinMode", "XOR");
        paramMap.put("activateRuleType", "directRunning");
        paramMap.put("invokePattern", "synchronous");
        paramMap.put("exceptionStrategy", "ignore");
        paramMap.put("executeAction", "");
        paramMap.put("splitMode", "XOR");
        paramMap.put("rollbackAction", "");
        paramMap.put("transactionType", "join");
        paramMap.put("participantType", "process-starter");
        paramMap.put("isAllowAppointParticipants", true);
        paramMap.put("id", dto.getBusiType());
        paramMap.put("finishType", dto.getBwpRepoFinishType());
        paramMap.put("triggerEvents", new Object[]{});
        paramMap.put("activityName", dto.getBwpRepoName());
        paramMap.put("apiVersion", dto.getBwpRepoVersion());
        paramMap.put("apiCode", dto.getBwpRepoCode());
        paramMap.put("activityType", dto.getBwpRepoType());
        paramMap.put("action", dto.getFlowApiRelaId());
        paramMap.put("limitTime", sdRepoLimitTimeDto.getFinishTimeLimit());
        paramMap.put("serviceUrl",dto.getApiUrl());
        // 创建环节 调用feign接口
        System.out.println(JSONObject.toJSONString(paramMap));
        R result = bwpOperDockingClient.createRepo(JSONObject.toJSONString(paramMap));
        if (!result.getCode().equals(BWP_CODE)) {
            log.info("生成环节失败");
            throw new GlobalException("流程环节创建失败", 500);
        }

        Map<String, Object> resultMap = (Map<String, Object>) result.getData();
        try {
            // 保存环节绑定
            sdApiFlowRepoBindEntity.setBwpId((String) resultMap.get("id"));
            sdApiFlowRepoBindEntity.setBwpRepoId((String) resultMap.get("repoId"));
            sdApiFlowRepoBindEntity.setBwpProcessDefName("0");
            sdApiFlowRepoBindEntity.setBwpRepoVersion("V" + 1 + ".0.0");
            sdApiFlowRepoBindEntity.setApiId(dto.getApiId());
            sdApiFlowRepoBindEntity.setBwpRepoCode(dto.getBwpRepoCode());
            sdApiFlowRepoBindEntity.setBwpRepoFinishType(dto.getBwpRepoFinishType());
            sdApiFlowRepoBindEntity.setBwpRepoName(dto.getBwpRepoName());
            sdApiFlowRepoBindEntity.setBwpRepoType(dto.getBwpRepoType());
            sdApiFlowRepoBindEntity.setShardingId(0);
            sdApiFlowRepoBindDao.insertApiBind(sdApiFlowRepoBindEntity);

            return true;
        } catch (Exception e) {
            log.error(ExceptionUtils.getStackTrace(e));
            return false;
        }
    }

    /**
     * API定义生成环节修改
     *
     * @param dto 流程绑定dto
     * @return boolean
     */
    @Override
    public boolean updateApiRepoBind(SdApiFlowRepoBindDto dto) {
        Map<String, Object> paramMap = new HashMap<>();
        Date date = new Date();
        SdApiFlowRepoBindEntity sdApiFlowRepoBindDto = new SdApiFlowRepoBindEntity();
        SdRepoLimitTimeEntity sdRepoLimitTimeDto = new SdRepoLimitTimeEntity();
        paramMap.put("splitMode", "XOR");
        paramMap.put("joinMode", "XOR");
        paramMap.put("id", dto.getBwpId());
        paramMap.put("finishType", dto.getBwpRepoFinishType());
        paramMap.put("invokePattern", "synchronous");
        paramMap.put("transactionType", "join");
        paramMap.put("exceptionStrategy", "ignore");
        paramMap.put("executeAction", "");
        paramMap.put("rollbackAction", "");
        paramMap.put("activateRuleType", "directRunning");
        paramMap.put("triggerEvents", new Object[]{});
        paramMap.put("apiVersion", dto.getBwpRepoVersion());
        paramMap.put("participantType", "process-starter");
        paramMap.put("activityType", dto.getBwpRepoType());
        paramMap.put("isAllowAppointParticipants", true);
        paramMap.put("action", dto.getFlowApiRelaId());
        paramMap.put("activityName", dto.getBwpRepoName());
        paramMap.put("limitTime", dto.getBwpRepoTimeLimit());
        paramMap.put("serviceUrl",dto.getApiUrl());
        //修改环节
        Integer result = bwpOperDockingClient.updateRepo(JSONObject.toJSONString(paramMap)).getCode();
        if (!result.equals(BWP_CODE)) {
            log.info("修改环节失败");
            throw new GlobalException("流程环节修改失败", 500);
        }
        try {
            // 更新环节绑定信息
            String oldVersion = dto.getBwpRepoVersion().split("\\.")[2];
            sdApiFlowRepoBindDto.setBwpRepoVersion("V1.0." + (Integer.parseInt(oldVersion) + 1));
            sdApiFlowRepoBindDto.setBwpRepoCode(dto.getBwpRepoCode());
            sdApiFlowRepoBindDto.setBwpRepoFinishType(dto.getBwpRepoFinishType());
            sdApiFlowRepoBindDto.setBwpRepoName(dto.getBwpRepoName());
            sdApiFlowRepoBindDto.setBwpRepoType(dto.getBwpRepoType());
            UpdateWrapper<SdApiFlowRepoBindEntity> wrapper = new UpdateWrapper<>();
            wrapper.eq("bwp_repo_id", dto.getBwpRepoId());
            sdApiFlowRepoBindDao.update(sdApiFlowRepoBindDto, wrapper);

        } catch (Exception e) {
            log.error(ExceptionUtils.getStackTrace(e));
            return false;
        }
        return true;
    }

    @Override
    public boolean deleteRepoBindByBwpId(String bwpId) {
        R result = bwpOperDockingClient.deleteRepo(bwpId);
        if (result.getCode() != 200) {
            throw new GlobalException("删除环节失败",500);
        }
        try {
            this.baseMapper.deleteRepoByBwpId(bwpId);
        }catch (Exception e){
            log.error("删除失败",e);
            return false;
        }
        return true;
    }


    /**
     * API定义 发布功能
     *
     * @param apiId api标识
     * @return boolean
     */
    @Override
    public boolean publishApi(String apiId,String apiCode,String optCode) {
        boolean result = false;
        if (apiId != null) {
            UpdateWrapper<SdApiDefineEntity> wrapper = new UpdateWrapper<>();
            // 更新api状态 10P发布 10DW下线
            if ("10P".equals(optCode)){
                wrapper.set("api_status", "10DW").set("modified_time", new Date())
                        .eq("api_code", apiCode)
                        .eq("api_status","10P")
                        .ne("api_version","V0.0.0");
                update(wrapper);
                wrapper.clear();
                wrapper.set("api_status", optCode).set("modified_time", new Date())
                        .eq("api_code", apiCode)
                        .eq("api_version","V0.0.0");
                update(wrapper);
            }else {
                wrapper.set("api_status", "10D").set("modified_time", new Date())
                        .eq("api_code", apiCode)
                        .eq("api_version","V0.0.0");
                update(wrapper);
            }
            wrapper.clear();
            wrapper.set("api_status", optCode).set("modified_time", new Date()).eq("api_id", apiId);
            result = update(wrapper);


        }
        return result;
    }

    @Override
    public List<SdApiFlowRepoBindEntity> queryBwpRepoIdByApiId(Integer[] apiId) {
        QueryWrapper<SdApiFlowRepoBindEntity> wrapper = new QueryWrapper<>();
        wrapper.in("api_id", apiId);
        return sdApiFlowRepoBindDao.selectList(wrapper);
    }

    @Override
    public String callOtherApi(SdApiCallInterface json) {
        String apiCode = json.getApiCode();
        log.info("========================{接受到参数：API编码：}========================" + apiCode);

        List<Map<String, Object>> apiParamValue = json.getApiInfo();
        Map<String, Object> map = apiParamValue.get(0);
        String param = JSON.toJSONString(map);
        log.info("========================{接收到参数：调用的实际参数值：}========================" + param);

        QueryWrapper<SdApiDefineEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("api_code", apiCode).ne("api_status", 1);
        String apiIp = sdApiDefineDao.selectOne(wrapper).getApiIp();
        Long apiId = sdApiDefineDao.selectOne(wrapper).getApiId();
        log.info("========================{需要调用的地址：}========================" + apiIp);

        String apiProvider = sdApiDefineDao.selectOne(wrapper).getApiProvider();
        log.info("========================{API提供方：}========================" + apiProvider);
        if (apiProvider.equals(API_PROVIDER)) {
            throw new GlobalException("该API是综合调度的");
        }

        QueryWrapper<SdApiParamEntity> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("api_id", apiId);
        SdApiParamEntity sdApiParamEntity = sdApiParamDao.selectOne(wrapper1);

        String paramType = sdApiParamEntity.getParamType();
        log.info("========================{参数的类型：}========================" + paramType);
        // 1) 调他方接口
        log.info("========================{调用开始：}========================");
        String list = otherInterface(apiIp, param, paramType, apiCode);
        log.info("========================{调用结束：返回结果：}========================" + list);

        // 2) 执行出参脚本
        String paramAnalyzeTemplate = sdApiParamEntity.getParamAnalyzeTemplate();
        log.info("========================{开始执行这个出参脚本：}========================" + paramAnalyzeTemplate);
        return (String) evalGroovyScript(paramAnalyzeTemplate, list);
    }

    @Override
    public String callOurApi(SdApiCallInterface sdApiCallInterface) {
        String apiCode = sdApiCallInterface.getApiCode();
        log.info("========================{接受到参数：API编码：}========================" + apiCode);

        List<Map<String, Object>> apiInfo = sdApiCallInterface.getApiInfo();
        Map<String, Object> map = apiInfo.get(0);
        String json = JSON.toJSONString(map);
        log.info("========================{接受到参数：入参json：}========================" + json);

        QueryWrapper<SdApiDefineEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("api_code", apiCode).ne("api_status", 1);
        SdApiDefineEntity sdApiDefineEntity = sdApiDefineDao.selectOne(wrapper);
        Long apiId = sdApiDefineEntity.getApiId();
        String apiIp = sdApiDefineEntity.getApiIp();
        log.info("========================{需要调用的地址：}========================" + apiIp);

        String apiProvider = sdApiDefineDao.selectOne(wrapper).getApiProvider();
        log.info("========================{API提供方：}========================" + apiProvider);
        if (!apiProvider.equals(API_PROVIDER)) {
            throw new GlobalException("该API不是综合调度的");
        }

        QueryWrapper<SdApiParamEntity> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("api_id", apiId);
        SdApiParamEntity sdApiParamEntity = sdApiParamDao.selectOne(wrapper1);
        String paramType = sdApiParamEntity.getParamType();
        log.info("========================{参数的类型：}========================" + paramType);

        // 1) 执行入参脚本
        String paramAnalyzeTemplate = sdApiParamEntity.getParamAnalyzeTemplate();
        log.info("========================{开始执行：出参脚本：}========================" + paramAnalyzeTemplate);
        String param = (String) evalGroovyScript(paramAnalyzeTemplate, json);
        log.info("========================{执行结束：结束：}========================" + param);
        // 2) 调我方接口
        return ourInterface(apiIp, param, paramType, apiCode);
    }

    /**
     * list转string
     *
     * @param list      list
     * @param separator 分割符
     * @return String
     */
    public static String listToString(List<Map<String, Object>> list, char separator) {
        return StringUtils.join(list.toArray(), separator);
    }

    /**
     * url+入参模板+参数类型 从缓存中读取出参数值 返回
     * TODO 待开发
     *
     * @param apiIp        调用的url
     * @param paramTemplate 参数模板
     * @param paramType     参数类型
     * @param apiCode       api编码
     * @return String
     */
    private String otherInterface(String apiIp, String paramTemplate, String paramType, String apiCode) {
        // 从缓存中取值 调用url
        String redis = ctgRedisUtils.getRedis(ConstantUtil.API_IN_PARAM + apiCode, CommonRedisGroupNameConst.DIC);
        // TODO 返回结果
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("dictCode", "API_STATUS");
        paramMap.put("name", "模拟返回结果");
        paramMap.put("value", "10D");
        return JSON.toJSONString(paramMap);
    }

    /**
     * url+入参模板+参数类型 从缓存中读取出参数值 返回
     * TODO 待开发
     *
     * @param apiIp        调用的url
     * @param paramTemplate 参数模板
     * @param paramType     参数类型
     * @param apiCode       api编码
     * @return String
     */
    private String ourInterface(String apiIp, String paramTemplate, String paramType, String apiCode) {
        // 从缓存中取值 调用url
        String redis = ctgRedisUtils.getRedis(ConstantUtil.API_IN_PARAM + apiCode, CommonRedisGroupNameConst.DIC);
        // TODO 模拟返回结果
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("name", "模拟返回结果");
        paramMap.put("dictCode", "API_STATUS");
        paramMap.put("value", "10D");
        return JSON.toJSONString(paramMap);
    }

    /**
     * 执行groovy脚本
     *
     * @param groovyScript 脚本
     * @param groovyParam  参数
     * @return Object
     */
    private Object evalGroovyScript(String groovyScript, Object groovyParam) {
        Class<?> groovyClass = GroovyUtil.parseClass(groovyScript);
        return GroovyUtil.executeGroovy(groovyClass, groovyParam);
    }

    /**
     * 根据apiCode查询api相关信息
     * @param apiCode
     * @return
     */
    @Override
    public SdApiDefineVo getApIByApiCode(String apiCode) {
        Map<String, Object> map = new HashMap<>(4);
        SdApiDefineVo data= new SdApiDefineVo();
        if(apiCode!=null&& !apiCode.equals("")){
             data=sdApiDefineDao.getApIByApiCode(apiCode);
        }
        return data;
    }

    @Override
    public List<SdApiDefineVo> getApIVersionByApiCode(String apiCode) {
        return sdApiDefineDao.getApIVersionByApiCode(apiCode);
    }
}
